package com.design.visitor.animal;

import java.util.ArrayList;
import java.util.List;

// 访问者接口
interface AnimalVisitor {
    void visit(Cat cat);
    void visit(Dog dog);
    void visit(Bird bird);
}

// 具体访问者类 - 兽医
class Veterinarian implements AnimalVisitor {
    @Override
    public void visit(Cat cat) {
        System.out.println("Veterinarian checking cat: " + cat.getName());
        // 实际检查逻辑...
    }

    @Override
    public void visit(Dog dog) {
        System.out.println("Veterinarian checking dog: " + dog.getName());
        // 实际检查逻辑...
    }

    @Override
    public void visit(Bird bird) {
        System.out.println("Veterinarian checking bird: " + bird.getName());
        // 实际检查逻辑...
    }
}

// 抽象元素类 - 动物
interface Animal {
    void accept(AnimalVisitor visitor);
    String getName();
}

// 具体元素类 - 猫
class Cat implements Animal {
    private String name;

    public Cat(String name) {
        this.name = name;
    }

    @Override
    public void accept(AnimalVisitor visitor) {
        visitor.visit(this);
    }

    @Override
    public String getName() {
        return name;
    }
}

// 具体元素类 - 狗
class Dog implements Animal {
    private String name;

    public Dog(String name) {
        this.name = name;
    }

    @Override
    public void accept(AnimalVisitor visitor) {
        visitor.visit(this);
    }

    @Override
    public String getName() {
        return name;
    }
}

// 具体元素类 - 鸟
class Bird implements Animal {
    private String name;

    public Bird(String name) {
        this.name = name;
    }

    @Override
    public void accept(AnimalVisitor visitor) {
        visitor.visit(this);
    }

    @Override
    public String getName() {
        return name;
    }
}

// 客户端代码
public class VisitorPatternExample {
    public static void main(String[] args) {
        List<Animal> animals = new ArrayList<>();
        animals.add(new Cat("Tom"));
        animals.add(new Dog("Buddy"));
        animals.add(new Bird("Polly"));

        Veterinarian veterinarian = new Veterinarian();
        for (Animal animal : animals) {
            animal.accept(veterinarian);
        }
    }
}
